package handler

import (
	"encoding/json"
	"fmt"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/application/service"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/infrastructure/async"
	"sen-golang-study/go_game_study/hero_story_go_server/game_server/internal/interfaces/context"
)

// UserLoginCmd 用户登录命令
type UserLoginCmd struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// UserLoginResult 用户登录结果
type UserLoginResult struct {
	UserID     uint32 `json:"userId"`
	Username   string `json:"username"`
	HeroAvatar uint32 `json:"heroAvatar"`
}

// UserLoginHandler 用户登录处理器
type UserLoginHandler struct {
	userLoginService        *service.UserLoginService
	sessionManagementService *service.SessionManagementService
}

// NewUserLoginHandler 创建用户登录处理器
func NewUserLoginHandler(userLoginService *service.UserLoginService, sessionManagementService *service.SessionManagementService) *UserLoginHandler {
	return &UserLoginHandler{
		userLoginService:        userLoginService,
		sessionManagementService: sessionManagementService,
	}
}

// HandleUserLogin 处理用户登录命令
func (h *UserLoginHandler) HandleUserLogin(ctx context.CmdContext, msgBody []byte) {
	// 解析登录命令
	var loginCmd UserLoginCmd
	err := json.Unmarshal(msgBody, &loginCmd)
	if err != nil {
		ctx.SendError(fmt.Sprintf("invalid login command: %v", err))
		return
	}

	// 验证输入参数
	if len(loginCmd.Username) == 0 {
		ctx.SendError("username cannot be empty")
		return
	}
	if len(loginCmd.Password) == 0 {
		ctx.SendError("password cannot be empty")
		return
	}

	// 异步执行登录
	h.userLoginService.LoginByPasswordAsync(loginCmd.Username, loginCmd.Password, func(result *async.AsyncResult) {
		if result.HasError() {
			ctx.SendError(fmt.Sprintf("login failed: %v", result.GetError()))
			return
		}

		// 获取登录结果
		loginData, ok := result.GetReturnValue().(map[string]interface{})
		if !ok {
			ctx.SendError("invalid login result")
			return
		}

		userID, ok := loginData["user_id"].(uint32)
		if !ok {
			ctx.SendError("invalid user ID in login result")
			return
		}

		username, ok := loginData["username"].(string)
		if !ok {
			ctx.SendError("invalid username in login result")
			return
		}

		heroAvatar, ok := loginData["hero_avatar"].(uint32)
		if !ok {
			ctx.SendError("invalid hero avatar in login result")
			return
		}

		// 绑定用户到上下文
		ctx.BindUserID(userID)

		// 绑定用户到会话
		if len(ctx.GetSessionID()) > 0 {
			err := h.sessionManagementService.BindUserToSession(ctx.GetSessionID(), userID)
			if err != nil {
				ctx.SendError(fmt.Sprintf("failed to bind user to session: %v", err))
				return
			}
		}

		// 构造登录结果
		loginResult := UserLoginResult{
			UserID:     userID,
			Username:   username,
			HeroAvatar: heroAvatar,
		}

		// 发送登录成功消息
		ctx.WriteMsg(10101, loginResult) // 10101 为用户登录结果消息码
	})
}